#include "persister.h"

#include <fstream>
#include <glog/logging.h>
#include <ios>
#include <iostream>
#include <mutex>
#include <string>
namespace raftStoreDataBase
{

    Persister::Persister( int index )
        : m_raftStateFileName( "raftStatePersister" + std::to_string( index ) + ".txt" )
        , m_snapShotFileName( "snapShotPersister" + std::to_string( index ) + ".txt" )
        , m_raftStateSize( 0 )
    {
        // 在这里还需要打开文件
        // 我们需要确保两个文件都能够正常正常打开
    }

    // 每次写入时都需要打开文件，不写入就不打开
    bool Persister::BothOpenFile()
    {
        m_raftStateOutPutStream.open( m_raftStateFileName, std::ios_base::out | std::ios_base::trunc );
        if ( !m_raftStateOutPutStream.is_open() )
        {
            std::cerr << "[func-Persister::Persister] " << m_raftStateFileName << "file open error" << std::endl;
            LOG( ERROR ) << "[func-Persister::Persister] " << m_raftStateFileName << "file open error";
            return false;
        }

        m_snapShotOutPutStream.open( m_snapShotFileName, std::ios_base::out | std::ios_base::trunc );

        if ( !m_snapShotOutPutStream.is_open() )
        {
            std::cerr << "[func-Persister::Persister] " << m_snapShotFileName << "file open error" << std::endl;
            LOG( ERROR ) << "[func-Persister::Persister] " << m_snapShotFileName << "file open error";
            return false;
        }

        return true;
    }

    void Persister::BothCloseFile()
    {
        m_raftStateOutPutStream.close();
        m_snapShotOutPutStream.close();
    }

    void Persister::BothSave( std::string raftstate, std::string snapshot )
    {
        std::lock_guard< std::mutex > lock( m_mutex );
        m_raftStateOutPutStream << raftstate;
        m_snapShotOutPutStream << snapshot;
        m_raftStateSize = raftstate.size();
    }

    void Persister::saveRaftState( const std::string &data )
    {
        std::lock_guard< std::mutex > lock( m_mutex );
        m_raftStateOutPutStream << data;
        m_raftStateSize = data.size();
    }

    std::string Persister::ReadRaftState()
    {
        std::lock_guard< std::mutex > lock( m_mutex );
        std::ifstream ifs( m_raftStateFileName, std::ios_base::in );
        if ( !ifs.is_open() )
        {
            std::cerr << m_raftStateFileName << " is open failed!" << std::endl;
            LOG( ERROR ) << m_raftStateFileName << " is open failed!";
            return "";
        }

        std::string raftState;
        ifs >> raftState;
        ifs.close();
        return raftState;
    }

    std::string Persister::ReadSnapShot()
    {
        std::lock_guard< std::mutex > lock( m_mutex );
        std::ifstream ifs( m_snapShotFileName, std::ios_base::in );
        if ( !ifs.is_open() )
        {
            std::cerr << m_snapShotFileName << " is open failed!" << std::endl;
            LOG( ERROR ) << m_snapShotFileName << " is open failed!";
            return "";
        }

        std::string snapShot;
        ifs >> snapShot;
        ifs.close();
        return snapShot;
    }

    Persister::~Persister()
    {
        if ( m_raftStateOutPutStream.is_open() )
        {
            m_raftStateOutPutStream.close();
        }
        if ( m_snapShotOutPutStream.is_open() )
        {
            m_snapShotOutPutStream.close();
        }
    }
}  // namespace raftStoreDataBase